package com.yikome.order.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.base.Preconditions;
import com.itmuch.lightsecurity.annotation.PreAuthorize;
import com.yikome.constant.CommonConstant;
import com.yikome.order.dto.OrderExportDTO;
import com.yikome.order.dto.OrderProductSearchDTO;
import com.yikome.order.dto.OrderSearchDTO;
import com.yikome.order.entity.Order;
import com.yikome.order.entity.OrderProduct;
import com.yikome.order.request.OrderEditRequest;
import com.yikome.order.request.OrderProductEditRequest;
import com.yikome.order.request.OrderSearchRequest;
import com.yikome.order.request.OrderToAdminRequest;
import com.yikome.order.service.OrderService;
import com.yikome.utils.BeanUtils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;

/**
 * admin order
 * 1.查询所有订单
 * 2.查询订单明细
 * 3.导出订单及明细
 * 4.取消订单
 * 5.挂起
 * 6.修改订单信息(价格,备注,收货人信息,优先级)
 * 7.订单商品数量修改(针对修改,取消)
 */
@RestController
@RequestMapping("/admin/order")
public class OrderController {

	@Autowired
	private OrderService orderService ;  
	
	
	@PutMapping("/api/create")
	public Boolean apiCreateOrder(@RequestBody OrderToAdminRequest request) {
		
		request.setSource("SHOP");
		request.setCreatedAt(DateUtil.date());
		orderService.asyncOrderToAdmin(request);
		
		return Boolean.TRUE;
	}
	
	@DeleteMapping("/api/{orderCode}/delete")
	public Boolean apiDeleteOrder(@PathVariable("orderCode") String orderCode) {
		
		orderService.deleteOrder(orderCode);
		
		return Boolean.TRUE;
	}
	
	
	@PutMapping("/uploads")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean uploadOrder(@RequestBody List<OrderToAdminRequest> uploads) {
		
		for (OrderToAdminRequest orderToAdminRequest : uploads) {
			
			orderToAdminRequest.setCode(IdUtil.fastSimpleUUID());
			orderToAdminRequest.setSource("UPLOAD");
			orderToAdminRequest.setIsBlackList(Boolean.FALSE);
			orderToAdminRequest.setCreatedAt(DateUtil.date());
			orderToAdminRequest.setStorehouseId(1L);
			
			orderService.asyncOrderToAdmin(orderToAdminRequest);
		}
		
		return Boolean.TRUE;
	}
	
	
	@GetMapping("/list")
	@PreAuthorize("hasAnyRoles('admin','analysis', 'affiliate', 'purchase', 'finance', 'order')")
	public Page<OrderSearchDTO> findOrderSearchDTO(OrderSearchRequest orderSearchRequest , @PageableDefault(direction = Direction.DESC , sort = {"o_order.id"})Pageable pageable){
		
		Page<OrderSearchDTO> contents = orderService.findOrderSearchDTO(orderSearchRequest , pageable);
		
		return contents ;
	}
	
	@GetMapping("/export")
	@PreAuthorize("hasAnyRoles('admin','analysis', 'finance')")
	public String exportOrderSearchDTO(OrderSearchRequest orderSearchRequest , @PageableDefault(direction = Direction.DESC , sort = {"o_order.id" , "o_order_product.product_sku_barcode"})Pageable pageable) throws Exception{
		
		List<OrderExportDTO> orderExportDTOs = orderService.findExportOrderSearchDTO(orderSearchRequest , PageRequest.of(0, 100000, Direction.DESC, "o_order.id" , "o_order_product.product_sku_barcode"));
		
		Map<String, OrderSearchDTO> oMap = new HashMap<>();
		for (OrderExportDTO orderExportDTO : orderExportDTOs) {
			
			OrderProductSearchDTO orderProductSearchDTO = new OrderProductSearchDTO();
			BeanUtils.copyProperties(orderExportDTO, orderProductSearchDTO);
			
			if(oMap.containsKey(orderExportDTO.getCode())) {
				oMap.get(orderExportDTO.getCode()).getProductSearchDTOs().add(orderProductSearchDTO);
			}else {
				
				OrderSearchDTO orderSearchDTO = new OrderSearchDTO();
				BeanUtils.copyProperties(orderExportDTO, orderSearchDTO);
				orderSearchDTO.setProductSearchDTOs(new ArrayList<>());
				
				orderSearchDTO.getProductSearchDTOs().add(orderProductSearchDTO);
				
				oMap.put(orderExportDTO.getCode(), orderSearchDTO);
			}
		}
		Collection<OrderSearchDTO> orderSearchDTOs = oMap.values();
		
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("订单明细", "订单明细"), OrderSearchDTO.class, orderSearchDTOs);
    	
    	String folderPath = CommonConstant.BASE_LOCATION + LocalDateTime.now(ZoneId.of("+8")).format(CommonConstant.DATETIMEFORMATTRT_DATE) + '/' ;
		File fileFolder = new File(folderPath);
		if (!fileFolder.exists())fileFolder.mkdirs();
		
		String fileName = LocalDateTime.now(ZoneId.of("+8")).format(CommonConstant.DATETIMEFORMATTRT_TIME) + "-订单明细.xlsx" ;
		
		String filePath = folderPath + fileName ;
		FileOutputStream fos = new FileOutputStream(filePath);
		workbook.write(fos);
        fos.close();
		return filePath ; 
	}
	
	@GetMapping("/{orderCode}/products")
	@PreAuthorize("hasAnyRoles('admin','analysis', 'affiliate', 'purchase', 'finance', 'order')")
	public List<OrderProductSearchDTO> findOrderProductSearchDTO(@PathVariable("orderCode") String orderCode){
		
		return orderService.findOrderProductInventorySearchDTO(orderCode);
	
	}
	
	@PutMapping("/{orderCode}/cancel")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean cancelOrder(@PathVariable("orderCode") String orderCode) {
		orderService.cancelOrder(orderCode);
		return Boolean.TRUE;
	}
	
	@PutMapping("/cancels")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean cancels(@RequestBody List<String> orderCodes) {
		
		for (String orderCode : orderCodes) {
			orderService.cancelOrder(orderCode);
		}
		
		return Boolean.TRUE;
	}
	
	@PutMapping("/deletes")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean deletes(@RequestBody List<String> orderCodes) {
		
		for (String orderCode : orderCodes) {
			orderService.deleteOrder(orderCode);
		}
		
		return Boolean.TRUE;
	}
	
	@DeleteMapping("/{orderCode}")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean deleteOrder(@PathVariable("orderCode") String orderCode) {
		orderService.deleteOrder(orderCode);
		return Boolean.TRUE;
	}
	
	@PutMapping("/{orderCode}/unHold")
	@PreAuthorize("hasAnyRoles('admin','order')")
	public Boolean unHoldOrder(@PathVariable("orderCode") String orderCode) {
		orderService.unHoldOrder(orderCode);
		return Boolean.TRUE;
	}
	
	@PutMapping("/{orderCode}/hold")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public Boolean holdlOrder(@PathVariable("orderCode") String orderCode) {
		orderService.holdlOrder(orderCode);
		return Boolean.TRUE;
	}
	
	@PutMapping("/{orderCode}")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public Order editOrder(@PathVariable("orderCode") String orderCode , @RequestBody OrderEditRequest orderEditRequest) {
		
		orderEditRequest.setOrderCode(orderCode);
		
		return orderService.editOrder(orderEditRequest);
	}
	
	@PutMapping("/{orderCode}/split")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public List<Order> splitOrder(@PathVariable("orderCode") String orderCode , @RequestBody List<Long> orderProductIds) {
		
		Preconditions.checkArgument(!orderProductIds.isEmpty(), "要拆单的数据不存在...");
		
		return orderService.splitOrder(orderCode, orderProductIds);
	}
	
	@PutMapping("/merge")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public Order mergeOrder(@RequestBody List<String> orderCodes) {
		
		return orderService.mergeOrder(orderCodes);
	}
	
	@PutMapping("/product/{orderProductId}")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public OrderProduct editOrderProduct(@PathVariable("orderProductId") Long orderProductId , @RequestBody OrderProductEditRequest orderProductEditRequest) {
		
		orderProductEditRequest.setOrderProductId(orderProductId);
		
		return orderService.editOrderProduct(orderProductEditRequest);
	}
	@DeleteMapping("/product/{orderProductId}")
	@PreAuthorize("hasAnyRoles('admin', 'order')")
	public boolean deleteOrderProduct(@PathVariable("orderProductId") Long orderProductId) {
		
		return orderService.deleteOrderProduct(orderProductId);
	}
}
